﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using CaltechSoft.Service.EntityFW.Entity;
using System.Data.Entity;
using CaltechSoft.Service.Infrastructure.Utility;

namespace CaltechSoft.Service.Repositories
{
    public class QuoteRepository : BaseRepository<Quote>
    {
        private static List<Quote> mock = new List<Quote>();

        public override async Task<int> Add(Quote entity)
        {

            //Guard.Against<Exception>(string.IsNullOrWhiteSpace(entity.QuoteNumber), "Quote Number can not be null!");

            using (var context = Context)
            {
                int customerId;
                string companyName;

                if (entity.Company != null)
                {
                    context.Customers.Add(entity.Company);
                    await context.SaveChangesAsync();
                    entity.CompanyId = entity.Company.Id;
                    customerId = entity.Company.Id;
                    companyName = entity.Company.Name;
                }
                else
                {
                    customerId = entity.CompanyId;
                    companyName = context.Customers.FirstOrDefault(x => x.Id == customerId).Name;
                }

                if (entity.Salesman != null)
                {
                    context.Users.Add(entity.Salesman);
                    entity.Salesman.UserName = entity.Salesman.FirstName + entity.Salesman.LastName;
                    entity.Salesman.Id = Guid.NewGuid().ToString();
                    await context.SaveChangesAsync();
                }

                //Add sale manager checkbox
                if (entity.ShowFullName)
                {
                    entity.ManagerId = entity.CreatedBy;
                }

                //Generate QuoteNumber
                var numberOfCustomerQuote = context.Quotes.Count(x => x.CreatedDate.HasValue && x.CreatedDate.Value.Year == DateTime.Now.Year && x.CreatedDate.Value.Month == DateTime.Now.Month && x.CreatedDate.Value.Day == DateTime.Now.Day);
                if (entity.QuoteDate.HasValue)
                {
                    numberOfCustomerQuote = context.Quotes.Count(x => x.QuoteDate.HasValue && x.QuoteDate.Value.Year == entity.QuoteDate.Value.Year && x.QuoteDate.Value.Month == entity.QuoteDate.Value.Month && x.QuoteDate.Value.Day == entity.QuoteDate.Value.Day);
                }
                // entity.QuoteNumber = "Q" + DateTime.Now.ToString("MMddyy") + "-" + (numberOfCustomerQuote + 1).ToString("00");
                var quoteNumber = GetQuoteNumber(context.Quotes, numberOfCustomerQuote, entity.QuoteDate);
                entity.QuoteNumber = quoteNumber;

                Guard.Against<Exception>(context.Quotes.Any(n => n.QuoteNumber == entity.QuoteNumber), "Quote Number can not be duplicated!");

                foreach (var item in entity.Items)
                {
                    context.QuoteItem.Add(item);
                }

                context.Quotes.Add(entity);
                return await context.SaveChangesAsync();
            }
        }

        private string GetQuoteNumber(DbSet<Quote> context, int number, DateTime? quoteDate)
        {
            number++;
            var quoteNumber = "Q" + (quoteDate.HasValue ? quoteDate.Value.ToString("MMddyy") : DateTime.Now.ToString("MMddyy")) + "-" + number.ToString("00");
            if (context.Where(n => n.QuoteNumber.Equals(quoteNumber)).Any())
            {
                quoteNumber = GetQuoteNumber(context, number, quoteDate);
                return quoteNumber;
            }
            else
            {
                return quoteNumber;
            }
        }

        public override async Task<int> Update(Quote updatedEntity)
        {
            // Temp code here
            using (var context = Context)
            {
                var updateEntry = context.Entry(updatedEntity);
                if (updateEntry.State == EntityState.Detached)
                {
                    var curAttachedEntity = context.Set<Quote>().FirstOrDefault(i => i.Id == updatedEntity.Id);

                    if (curAttachedEntity != null)
                    {
                        var attachedEntry = context.Entry(curAttachedEntity);
                        attachedEntry.CurrentValues.SetValues(updatedEntity);
                        var listModified = attachedEntry.CurrentValues.PropertyNames.Where(p => attachedEntry.Property(p).IsModified).ToList();

                        if (listModified.Contains("ShowFullName") && updatedEntity.ShowFullName)
                        {
                            updatedEntity.ManagerId = updatedEntity.UpdatedBy;
                        }

                        if (listModified.Count == 3 && listModified.Contains("ShowFullName") && listModified.Contains("UpdatedBy") && listModified.Contains("UpdatedDate"))
                        {
                            attachedEntry.Property(e => e.UpdatedBy).IsModified = false;
                            updatedEntity.UpdatedBy = curAttachedEntity.UpdatedBy;
                        }
                    }
                    else
                    {
                        updateEntry.State = EntityState.Modified;
                    }
                }

                if (updatedEntity.Company != null)
                {
                    context.Customers.Attach(updatedEntity.Company);
                    var customerEntry = context.Entry(updatedEntity.Company);
                    customerEntry.Property(e => e.Email).IsModified = true;
                    customerEntry.Property(e => e.Address).IsModified = true;
                    customerEntry.Property(e => e.ContactPersonName).IsModified = true;
                    customerEntry.Property(e => e.Tel).IsModified = true;
                    customerEntry.Property(e => e.Mobile).IsModified = true;
                    customerEntry.Property(e => e.Name).IsModified = true;

                }

                if (updatedEntity.Salesman != null)
                {
                    updatedEntity.Salesman.UserName = updatedEntity.Salesman.LastName;
                    context.Users.Attach(updatedEntity.Salesman);
                    var salemanEntry = context.Entry(updatedEntity.Salesman);
                    salemanEntry.Property(e => e.Email).IsModified = true;
                    salemanEntry.Property(e => e.Tel).IsModified = true;
                    salemanEntry.Property(e => e.PhoneNumber).IsModified = true;
                    salemanEntry.Property(e => e.LastName).IsModified = true;
                }


                var attachedEntity = await context.Quotes.FirstOrDefaultAsync(x => x.Id == updatedEntity.Id);

                context.QuoteItem.RemoveRange(attachedEntity.Items);

                foreach (var item in updatedEntity.Items)
                {
                    item.QuoteId = updatedEntity.Id;
                    context.QuoteItem.Add(item);
                }

                await context.SaveChangesAsync();

                return await base.Update(updatedEntity);
            }
        }
    }
}